﻿Imports System.Reflection
Imports System.ComponentModel.Composition
Imports System.ComponentModel.Composition.Hosting
Imports Pronama.NamaAlert.ViewModel


Public Class AlertEngine

    Private WithEvents MainViewModel As MainViewModel
    Private WithEvents MainPage As MainPage


    Private SettingsDictionary As New Dictionary(Of String, Settings)
    Private Helper As AddInHelper

    <ImportMany(GetType(ISourceAddIn), AllowRecomposition:=True)>
    Property SourceAddIns As IEnumerable(Of Lazy(Of ISourceAddIn, IAddInMetaData))

    <ImportMany(GetType(IDestinationAddIn), AllowRecomposition:=True)>
    Property DestinationAddIns As IEnumerable(Of Lazy(Of IDestinationAddIn, IAddInMetaData))

    <Export(GetType(WriteLogCallback))>
    Public Sub WriteLog(ByVal sourceAddIn As IAddIn, ByVal log As Log)

        For Each addIn In MainViewModel.DestinationAddInItems
            If addIn.IsEnabled Then
                addIn.WriteLog(sourceAddIn, log)
            End If
        Next

    End Sub

    <Export(GetType(PostMessageCallback))>
    Public Sub PostMessage(ByVal sourceAddIn As IAddIn, ByVal message As Message)

        For Each addIn In MainViewModel.DestinationAddInItems
            If addIn.IsEnabled Then
                addIn.ReceiveMessage(sourceAddIn, message)
            End If
        Next

    End Sub

    Private DeploymentCatalogs As New Queue(Of DeploymentCatalog)

    Public Sub Run(ByVal mainPage As MainPage, ByVal viewModel As MainViewModel)
        Me.MainViewModel = viewModel
        Me.MainPage = mainPage

        Me.Helper = New AddInHelper(mainPage.Dispatcher)
        LoadSettings()

        Dim catalog = New AggregateCatalog
        catalog.Catalogs.Add(DownloadCatalog("AddIn.Default.xap"))
        'catalog.Catalogs.Add(DownloadCatalog("AddIn.DefaultAlert.xap"))
        'catalog.Catalogs.Add(DownloadCatalog("AddIn.NicoLiveAlertSource"))
        DeploymentCatalogs.Dequeue.DownloadAsync()

        Dim container = New CompositionContainer(catalog)
        Try
            container.ComposeParts(Me)
        Catch ex As ReflectionTypeLoadException
#If DEBUG Then
            'MessageBox.Show(ex.LoaderExceptions.FirstOrDefault.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Exclamation)
            Stop
#End If
        End Try

    End Sub

    Private Function DownloadCatalog(ByVal uriRelative As String) As DeploymentCatalog
        Dim c = New DeploymentCatalog(uriRelative)
        AddHandler c.DownloadCompleted, AddressOf CatalogDownloadCompleted
        DeploymentCatalogs.Enqueue(c)
        'c.DownloadAsync()
        Return c
    End Function


    Private Function GetSettings(ByVal guid As String) As Settings
        Dim s As Settings = Nothing
        If SettingsDictionary.ContainsKey(guid) Then
            s = SettingsDictionary(guid)
        Else
            s = New Settings
            SettingsDictionary.Add(guid, s)
        End If
        Return s
    End Function

    Public Sub LoadSettings()
        'Dim file = System.IO.Path.Combine(My.Application.Info.DirectoryPath, "MisaoSettings.xml")
        'If Not System.IO.File.Exists(file) Then
        '    Exit Sub
        'End If

        'Try
        '    Dim doc = XDocument.Load(file)
        '    For Each s In doc...<settings>

        '        If s.@id = "" OrElse SettingsDictionary.ContainsKey(s.@id) Then
        '            Continue For
        '        End If

        '        Dim settings = New Settings
        '        settings.Deserialize(s)
        '        SettingsDictionary.Add(s.@id, settings)
        '    Next
        'Catch ex As Exception
        '    MessageBox.Show(ex.Message, "Settings Loading Error", MessageBoxButton.OK, MessageBoxImage.Exclamation)
        'End Try

    End Sub

    Public Sub SaveSettings()
        'Dim file = System.IO.Path.Combine(My.Application.Info.DirectoryPath, "MisaoSettings.xml")


        'Dim xe = New XElement("misao")
        'For Each key In SettingsDictionary.Keys
        '    Dim se = SettingsDictionary(key).Serialize
        '    se.@id = key
        '    xe.Add(se)
        'Next

        'Dim doc = <?xml version="1.0" encoding="UTF-8"?>
        '          <%= xe %>

        'Try
        '    doc.Save(file)
        'Catch ex As Exception
        '    MessageBox.Show(ex.Message, "Settings Saving Error", MessageBoxButton.OK, MessageBoxImage.Exclamation)
        'End Try

    End Sub

    Public Sub Close()
        SaveSettings()

        For Each AddIn In MainViewModel.SourceAddInItems
            AddIn.Deactivate()
        Next
        For Each AddIn In MainViewModel.DestinationAddInItems
            AddIn.Deactivate()
        Next
    End Sub

    'Private Sub MainWindow_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles MainWindow.Closed
    '    Close()
    'End Sub

    Private Sub CatalogDownloadCompleted(ByVal sender As Object, ByVal e As ComponentModel.AsyncCompletedEventArgs)

        Try
            If Not e.Error Is Nothing Then
                ' TODO AddIn ロード失敗処理
                Exit Sub
            End If

            ' Source AddIns
            For Each addIn In SourceAddIns

                Dim target = addIn
                Dim addins = From a In MainViewModel.SourceAddInItems
                             Where a.Guid.Equals(New Guid(target.Metadata.Guid))

                If addins.Count = 0 Then
                    Dim addInViewModel = New SourceAddInViewModel(addIn) With {.Settings = GetSettings(addIn.Metadata.Guid)}
                    MainViewModel.SourceAddInItems.Add(addInViewModel)

                    addInViewModel.Helper = Me.Helper
                    addInViewModel.Settings = GetSettings(addIn.Metadata.Guid)
                    addInViewModel.Activate()

                    'MainPage.TabChildGrid.Children.Clear()
                    'Dim control = addInViewModel.GetContentControl(Nothing)
                    'MainPage.TabChildGrid.Children.Add(control)

                End If
            Next

            ' Dest AddIns
            For Each addIn In DestinationAddIns

                Dim target = addIn
                Dim addins = From a In MainViewModel.DestinationAddInItems
                             Where a.Guid.Equals(New Guid(target.Metadata.Guid))

                If addins.Count = 0 Then
                    Dim addInViewModel = New DestinationAddInViewModel(addIn) With {.Settings = GetSettings(addIn.Metadata.Guid)}
                    MainViewModel.DestinationAddInItems.Add(addInViewModel)

                    addInViewModel.Helper = Me.Helper
                    addInViewModel.Settings = GetSettings(addIn.Metadata.Guid)
                    addInViewModel.Activate()

                    If addInViewModel.HasSidebar Then
                        MainPage.SidebarGrid.Children.Clear()
                        Dim sidebar = addInViewModel.GetSidebarControl
                        MainPage.SidebarGrid.Children.Add(sidebar)
                    End If

                    'MainPage.TabChildGrid.Children.Clear()
                    'Dim control = addInViewModel.GetContentControl(Nothing)
                    'MainPage.TabChildGrid.Children.Add(control)

                End If
            Next
        Catch ex As Exception
#If DEBUG Then
            Stop
#End If
        Finally
            If DeploymentCatalogs.Count > 0 Then
                DeploymentCatalogs.Dequeue.DownloadAsync()
            Else
                MainViewModel.IsBusy = False
            End If
        End Try
    End Sub


End Class
